package com.wpml.orm;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.*;
import java.util.Arrays;
import java.util.Date;

public class JdbcUtils {

    static String url = "jdbc:mysql://8.141.50.71:3306/msb_uc";
    static String username = "root";
    static String password = "root";

    /**
     * 获取数据库连接
     * @return 返回连接
     * @throws SQLException 异常
     * @throws ClassNotFoundException 异常
     */
    public static Connection getConnection() throws SQLException, ClassNotFoundException {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 执行查询
     * @param querySQL sql语句
     * @param handler 处理结果集handler
     * @param args 入参
     * @param <T> 泛型
     * @return 返回结果对象
     * @throws Exception 异常
     */
    public static <T> T execQuery(String querySQL, OrmHandler<T> handler, Object...args) throws Exception{
        Connection connection = getConnection();

        Statement statement = connection.createStatement();

        ResultSet resultSet = statement.executeQuery(querySQL);

        System.out.printf("查询SQL：%s%n", querySQL);

        return  handler.handler(resultSet);
    }

    /**
     * 列与对象字段对照关系
     * @param resultSet 查询结果集
     * @param declaredFields 对象字段集
     * @return 对照关系数组
     * @throws Exception 异常
     */
    public static int[] column2Property(ResultSet resultSet, Field[] declaredFields)  throws Exception{
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();

        int[] column2Property = new int[columnCount + 1];
        Arrays.fill(column2Property, -1); // 初始化数组值为 -1
        // 找到查询列与对象属性之间对应关系
        for (int i = 1; i < columnCount + 1; i++) {
            for (int j = 0; j < declaredFields.length; j++) {
                if (metaData.getColumnName(i).equalsIgnoreCase(declaredFields[j].getName())) {
                    column2Property[i] = j;
                }
            }
        }
        return  column2Property;
    }

    /**
     * 结果转对象
     * @param resultSet 查询结果集
     * @param column2Property 对照关系数组
     * @param clazz 返回对象Class
     * @param <T> 泛型
     * @return 返回结果对象
     * @throws Exception 异常信息
     */
    public static  <T> T result2PO(ResultSet resultSet, int[] column2Property, Class<T> clazz) throws Exception {
        T newInstance = clazz.newInstance();
        Field[] declaredFields = clazz.getDeclaredFields();

        for (int i = 1; i < column2Property.length; i++) {
            if (column2Property[i] != -1) {
                Field field = declaredFields[column2Property[i]];
                field.setAccessible(true);
                Class<?> type = field.getType();
                if (type == Integer.class || type == Integer.TYPE) {
                    field.set(newInstance, resultSet.getInt(i));
                } else if (type == String.class) {
                    field.set(newInstance, resultSet.getString(i));
                } else if (type == Long.class || type == Long.TYPE) {
                    field.set(newInstance, resultSet.getLong(i));
                } else if (type == Byte.class || type == Byte.TYPE) {
                    field.set(newInstance, resultSet.getByte(i));
                } else if (type == BigDecimal.class) {
                    field.set(newInstance, resultSet.getBigDecimal(i));
                } else if (type == Date.class) {
                    field.set(newInstance, resultSet.getDate(i));
                } else if (type == Object.class) {
                    field.set(newInstance, resultSet.getObject(i));
                }
            }
        }

        return newInstance;
    }
}
